package com.ecas.code.generator.enums;

import com.ecas.code.generator.exception.UnknownDataTypeException;
import com.google.common.base.Strings;

import java.text.SimpleDateFormat;
import java.util.Date;

public enum ValueTypeEnum {

    CHAR("char", "String", "String", "string"),
    VARCHAR("varchar", "String", "String", "string"),
    LONGVARCHAR("longvarchar", "String", "String", "string"),
    NUMBER("number", "BigDecimal", "BigDecimal", "uint64"),
    DECIMAL("decimal", "BigDecimal", "BigDecimal", "uint64"),
    BOOLEAN("boolean", "boolean", "Boolean", "bool"),
    TINYINT("tinyint", "byte", "Byte", "bytes"),
    SMALLINT("mediumblob", "short", "Short", "uint32"),
    INTEGER("int", "int", "Integer", "uint32"),
    BIGINT("bigint", "long", "Long", "uint64"),
    BYTEARRAY("byte[]", "byte[]", "Byte[]", "bytes"),
    DATE("date", "Date", "Date", "string"),
    FLOAT("float", "float", "Float", "float"),
    DOUBLE("Double", "double", "Double", "double"),
    LONGTEXT("lonetext", "String", "String", "string"),
    DATETIME("datetime", "Date", "Date", "string"),
    TIMESTAMP("timestamp", "Timestamp", "Timestamp", "uint64"),
    SET("set", "Set", "Set", ""),
    ENUM("enum", "enum", "Enum", "enum"),
    LONGBLOB("longblob", "String", "String", "string"),
    MEDIUMTEXT("mediumtext", "String", "String", "string"),
    MEDIUMBLOB("mediumblob", "String", "String", "string"),
    TEXT("text", "String", "String", "string"),
    BLOB("blob", "String", "String", "string"),
    TIME("time", "Date", "Date", "string"),
    GEOMETRY("geometry", "", "", ""),
    YEAR("year", "int", "Integer", "uint32"),
    MEDIUMINT("mediumint", "int", "int", "uint32");


    private final String jdbcLowerType;
    private final String javaBaseTypeType;
    private final String javaObjectType;
    private final String pbType;
    private static final String UNKNOWN_TYPE_MESSAGE = "nkonw Type,valueTypeStr:";


    private ValueTypeEnum(String jdbcLowerType, String javaBaseTypeType, String javaObjectType, String pbType) {
        this.jdbcLowerType = jdbcLowerType;
        this.javaBaseTypeType = javaBaseTypeType;
        this.javaObjectType = javaObjectType;
        this.pbType = pbType;
    }

    public static ValueTypeEnum parse(String valueTypeStr) {
        ValueTypeEnum[] values = ValueTypeEnum.values();
        for (ValueTypeEnum value : values) {
            if (value.getJdbcLowerType().equalsIgnoreCase(valueTypeStr)) {
                return value;
            }
        }

        return null;
    }

    public static String parseToJavaObjectType(String valueTypeStr) {
        ValueTypeEnum valueTypeEnum = ValueTypeEnum.parse(valueTypeStr);
        if (valueTypeEnum == null) {
            throw new UnknownDataTypeException(UNKNOWN_TYPE_MESSAGE + valueTypeEnum);
        }
        return valueTypeEnum.getJavaObjectType();
    }

    public static String parseToJavaBaseType(String valueTypeStr) {
        ValueTypeEnum valueTypeEnum = ValueTypeEnum.parse(valueTypeStr);
        if (valueTypeEnum == null) {
            throw new UnknownDataTypeException(UNKNOWN_TYPE_MESSAGE + valueTypeEnum);
        }
        return valueTypeEnum.getJavaBaseTypeType();
    }

    public static String parseToJdbcLowerType(String valueTypeStr) {
        ValueTypeEnum valueTypeEnum = ValueTypeEnum.parse(valueTypeStr);
        if (valueTypeEnum == null) {
            throw new UnknownDataTypeException(UNKNOWN_TYPE_MESSAGE + valueTypeEnum);
        }
        return valueTypeEnum.getJdbcLowerType();
    }

    public static String parseToPbType(String valueTypeStr) {
        ValueTypeEnum valueTypeEnum = ValueTypeEnum.parse(valueTypeStr);
        if (valueTypeEnum == null) {
            throw new UnknownDataTypeException(UNKNOWN_TYPE_MESSAGE + valueTypeEnum);
        }
        return valueTypeEnum.getPbType();
    }

    public static Object parseFieldValue(ValueTypeEnum valueType, String valueFormat, String valueStr) {
        if (Strings.isNullOrEmpty(valueStr)) {
            return null;
        }
        try {

            if (valueType.equals(ValueTypeEnum.VARCHAR)) {
                return valueStr;
            } else if (valueType.equals(ValueTypeEnum.INTEGER)) {
                Integer returnValue_int = java.lang.Integer.valueOf(valueStr);
                return returnValue_int;

            } else if (valueType.equals(ValueTypeEnum.FLOAT)) {

                Float returnValue_float = java.lang.Float.valueOf(valueStr);
                return returnValue_float;


            } else if (valueType.equals(ValueTypeEnum.DOUBLE)) {
                Double returnValue_double = java.lang.Double.valueOf(valueStr);
                return returnValue_double;

            } else if (valueType.equals(ValueTypeEnum.BIGINT)) {

                Long returnValue_long = java.lang.Long.valueOf(valueStr);
                return returnValue_long;

            } else if (valueType.equals(ValueTypeEnum.BOOLEAN)) {

                Boolean returnValue_boolean = java.lang.Boolean.valueOf(valueStr);
                return returnValue_boolean;

            } else if (valueType.equals(ValueTypeEnum.DATETIME)) {
                return parseDateFieldValue(valueType, valueFormat, valueStr);
            } else {
                throw new UnknownDataTypeException(UNKNOWN_TYPE_MESSAGE + ",valueFormat:" + valueFormat + ",valueStr:" + valueStr);
            }
        } catch (Exception e) {
            throw e;
        }

    }

    public static Object parseDateFieldValue(ValueTypeEnum valueType, String valueFormat, String valueStr) {
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(valueFormat);
            Date date = simpleDateFormat.parse(valueStr);
            return date;
        } catch (Exception e) {
            throw new UnknownDataTypeException(UNKNOWN_TYPE_MESSAGE + valueType + ",valueFormat:" + valueFormat + ",valueStr:" + valueStr, e);
        }
    }


    public String getJdbcLowerType() {
        return jdbcLowerType;
    }

    public String getJavaBaseTypeType() {
        return javaBaseTypeType;
    }

    public String getJavaObjectType() {
        return javaObjectType;
    }

    public String getPbType() {
        return pbType;
    }
}